package com.ruoyi.common.utils;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.metadata.BeanDescriptor;
import javax.validation.metadata.ConstraintDescriptor;
import javax.validation.metadata.PropertyDescriptor;
import javax.xml.bind.ValidationException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @description: 校验工具类
 * @author liuyachao
 * @date 2021/9/18 16:38
 */
public class ValidationUtil {

    private static final Validator validator;

    static {
        ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
        validator = vf.getValidator();
    }

    /**
     * javax.validation注解校验
     * @throws ValidationException
     * @throws ValidationException
     * @Description: 校验方法
     * @param t 将要校验的对象
     * @throws ValidationException
     * void
     * @throws
     */
    public static <T> List<String> validate(T t) {
        return validate(t, null);
    }


    /**
     * 获取某一个校验规则下的必填字段
     */
    public static <T> List<String> getValidateProperty(T t, Class<?> group) {
        BeanDescriptor beanDescriptor = validator.getConstraintsForClass(t.getClass());
        Set<PropertyDescriptor> constrainedProperties = beanDescriptor.getConstrainedProperties();

        Set<String> propertySet = new HashSet<>();
        for (PropertyDescriptor constrainedProperty : constrainedProperties) {
            Set<ConstraintDescriptor<?>> constraintDescriptors = constrainedProperty.getConstraintDescriptors();
            for (ConstraintDescriptor<?> constraintDescriptor : constraintDescriptors) {
                Set<Class<?>> groups1 = constraintDescriptor.getGroups();
                if (groups1.contains(group)) {
                    propertySet.add(constrainedProperty.getPropertyName());
                    break;
                }
            }
        }

        return new ArrayList<>(propertySet);
    }

    public static <T> List<String> validate(T t, Class<?>... groups) {
        Set<ConstraintViolation<T>> set;
        if (groups != null && groups.length > 0) {
            set = validator.validate(t, groups);
        } else {
            set = validator.validate(t);
        }

        List<String> validateError = new ArrayList<>();
        if (set.size() > 0) {
            for (ConstraintViolation<T> val : set) {
                System.out.println(val.getPropertyPath());
                validateError.add(val.getMessage());
            }
        }
        return validateError;
    }
}
